package com.codeplatform.config;

import com.codeplatform.util.ColorLogger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;

/**
 * HTTP请求日志拦截器
 * 记录API请求和响应的详细信息，使用彩色日志输出
 */
@Slf4j
@Component
public class LoggingInterceptor implements HandlerInterceptor {

    private static final String REQUEST_START_TIME = "requestStartTime";
    private static final String REQUEST_ID = "requestId";

    /**
     * 请求处理前的日志记录
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long startTime = System.currentTimeMillis();
        String requestId = ColorLogger.generateRequestId();
        
        // 存储请求开始时间和请求ID
        request.setAttribute(REQUEST_START_TIME, startTime);
        request.setAttribute(REQUEST_ID, requestId);
        
        // 记录请求信息
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();
        String fullUrl = queryString != null ? uri + "?" + queryString : uri;
        
        // 输出彩色请求日志
        ColorLogger.apiRequest(method, fullUrl, requestId);
        
        // 记录请求头信息（调试模式）
        if (log.isDebugEnabled()) {
            logRequestHeaders(request, requestId);
        }
        
        // 记录请求参数
        if (log.isDebugEnabled() && request.getParameterMap().size() > 0) {
            logRequestParameters(request, requestId);
        }
        
        return true;
    }

    /**
     * 请求处理后的日志记录
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 这里可以记录控制器处理完成后的信息
    }

    /**
     * 请求完成后的日志记录
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        Long startTime = (Long) request.getAttribute(REQUEST_START_TIME);
        String requestId = (String) request.getAttribute(REQUEST_ID);
        
        if (startTime != null && requestId != null) {
            long duration = System.currentTimeMillis() - startTime;
            String method = request.getMethod();
            String uri = request.getRequestURI();
            int statusCode = response.getStatus();
            
            // 输出彩色响应日志
            ColorLogger.apiResponse(method, uri, statusCode, duration, requestId);
            
            // 记录性能信息
            if (duration > 1000) {
                ColorLogger.performance("慢请求", duration, String.format("%s %s", method, uri));
            }
            
            // 记录异常信息
            if (ex != null) {
                ColorLogger.error("请求处理异常: %s %s [请求ID: %s]", ex, method, uri, requestId);
            }
            
            // 记录响应头信息（调试模式）
            if (log.isDebugEnabled()) {
                logResponseHeaders(response, requestId);
            }
        }
    }

    /**
     * 记录请求头信息
     */
    private void logRequestHeaders(HttpServletRequest request, String requestId) {
        ColorLogger.debug("请求头信息 [请求ID: %s]:", requestId);
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            String headerValue = request.getHeader(headerName);
            
            // 隐藏敏感信息
            if (isSensitiveHeader(headerName)) {
                headerValue = "[隐藏]";
            }
            
            ColorLogger.debug("  %s: %s", headerName, headerValue);
        }
    }

    /**
     * 记录请求参数
     */
    private void logRequestParameters(HttpServletRequest request, String requestId) {
        ColorLogger.debug("请求参数 [请求ID: %s]:", requestId);
        request.getParameterMap().forEach((key, values) -> {
            String value = String.join(", ", values);
            
            // 隐藏敏感参数
            if (isSensitiveParameter(key)) {
                value = "[隐藏]";
            }
            
            ColorLogger.debug("  %s: %s", key, value);
        });
    }

    /**
     * 记录响应头信息
     */
    private void logResponseHeaders(HttpServletResponse response, String requestId) {
        ColorLogger.debug("响应头信息 [请求ID: %s]:", requestId);
        response.getHeaderNames().forEach(headerName -> {
            String headerValue = response.getHeader(headerName);
            ColorLogger.debug("  %s: %s", headerName, headerValue);
        });
    }

    /**
     * 判断是否为敏感请求头
     */
    private boolean isSensitiveHeader(String headerName) {
        String lowerCaseName = headerName.toLowerCase();
        return lowerCaseName.contains("authorization") ||
               lowerCaseName.contains("cookie") ||
               lowerCaseName.contains("token") ||
               lowerCaseName.contains("password") ||
               lowerCaseName.contains("secret");
    }

    /**
     * 判断是否为敏感参数
     */
    private boolean isSensitiveParameter(String paramName) {
        String lowerCaseName = paramName.toLowerCase();
        return lowerCaseName.contains("password") ||
               lowerCaseName.contains("token") ||
               lowerCaseName.contains("secret") ||
               lowerCaseName.contains("key") ||
               lowerCaseName.contains("credential");
    }
}